/*
    Spherical Grid Volume Approximation: An algorithm for approximating the 
    volume of a compound object by keeping track of its members' positions in space.
    Copyright (C) 2009, Rodrigo Castano, FuDePAN

    This file is part of Spherical Grid Volume Approximation.

    Spherical Grid Volume Approximation is free software: you can redistribute 
    it and/or modify it under the terms of the GNU General Public License as published 
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Spherical Grid Volume Approximation is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#include "grillado.h"


class GrilladoOriginal : public Grillado<unsigned int> {
public:	
	
	GrilladoOriginal(size_t a, size_t b, size_t c, Length R, Length D) throw 
			(Grillado<unsigned int>::radiusOrDistanceParamException, Grillado<unsigned int>::sizeParamException, bad_alloc);

	
	esferaId add_element(Coord x, Coord y, Coord z) ;

	
	inline void remove_element(Coord x, Coord y, Coord z) throw (gridPositionException);
	
	inline void remove_element(const esferaId &id) throw (gridPositionException);
	
private:

	inline void add_element(const esferaId &id) ;
	
	inline esferaId obtener_id(Coord x, Coord y, Coord z) const;
};




inline esferaId GrilladoOriginal::obtener_id(Coord x, Coord y, Coord z) const {
	GridCoord temp[3];
	calcular_coord(x,y,z,temp[0],temp[1],temp[2]);
	return esferaId(temp[0],temp[1],temp[2]);
}


// Se agrega un elemento a la esfera correspondiente a las coordenadas ingresadas
// como argumento.
// Adds an element to the sphere determined by coordinates x, y, z.


inline void GrilladoOriginal::add_element(const esferaId &id)  {
	const GridCoord coord_x = id.get_m();
	const GridCoord coord_y = id.get_n();
	const GridCoord coord_z = id.get_z();
	if(matriz[coord_x][coord_y][coord_z] == 0 ) {
		aumentar_vol_parcial(coord_x,coord_y,coord_z);
	}
	matriz[coord_x][coord_y][coord_z]++;
}

// Se quita un elemento de la esfera correspondiente a las coordenadas ingresadas
// como argumento.
// Removes an element from the sphere determined by coordinates x, y, z.


inline void GrilladoOriginal::remove_element(const esferaId &id) throw (gridPositionException) {
	const GridCoord coord_x = id.get_m();
	const GridCoord coord_y = id.get_n();
	const GridCoord coord_z = id.get_z();
	if (matriz[coord_x][coord_y][coord_z] == 0) {
		throw gridPositionException();
	}
	matriz[coord_x][coord_y][coord_z]--;
	if (matriz[coord_x][coord_y][coord_z] == 0) {
		reducir_vol_parcial(coord_x,coord_y,coord_z);
	}
}

